/**
 * Created by Richard Radlherr.
 * Date: 04.06.2006 21:59
 */

using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using TagTool.Core;

namespace TagTool.Components
{
	
	public partial class InputSlotPanel
	{
		Brush brush = new SolidBrush(Color.Black);
		OutputSlotPanel input = null;
		
		Pen pen;

		public InputSlotPanel(InputSlot slot)
		{
			InitializeComponent();
			this.Tag = slot;
			this.slotName.Text = slot.Name;
			this.Name = slot.Name;
			UpdateValueText();
			slotValue.Enabled = slot.Editable;
			activeEventHandling.CheckState = Slot.Active ? CheckState.Checked : CheckState.Unchecked;
			pen = new Pen(ColorTable.Instance.GetColor(slot.DefaultValue.GetType()));
			brush = new SolidBrush(pen.Color);
			Attach();
		}
		
		
		public InputSlot Slot
		{
			get { return (InputSlot)Tag; }
		}
		
		public OutputSlotPanel Connection
		{
			get { return input; }
		}
		
		public void Connect(OutputSlotPanel panel)
		{
			UnConnect();
			Slot.Connect(panel.Slot);
			input = panel;
			input.AddConnection(this);
			if (Slot.Active)
			{
				Attach();
			}
			UpdateValueText();
		}
		
		public void UnConnect()
		{
			if (input != null)
			{
				if (Slot.Active)
				{
					Detach();
				}
				input.RemoveConnection(this);
				Slot.UnConnect();
				input = null;
			}
		}

		private void ValueChanged(object sender, ValueChangedEventArgs e)
		{
			slotValue.Text = e.Value.ToString();
		}
		
		public void UpdateValueText()
		{
			slotValue.Text = ((Slot)Tag).Value.ToString();
		}
	
		public void PaintConnection(Graphics g)
		{
			if (input != null)
			{
				int x1 = input.Parent.Right;
				int y1 = input.Top + input.Parent.Top;
				int x2 = Parent.Left;
				int y2 = Top + Parent.Top;
				
				pen.Width = 10;
				g.DrawLine(pen, x1, y1 + 7, x1 + 5, y1 + 7);
				g.DrawLine(pen, x2, y2 + 7, x2 - 5, y2 + 7);
				
				pen.Width = 3;
				g.DrawLine(pen, x1 + 4, y1 + 7, x2 - 5, y2 + 7);
			}
		}
		
		void SlotNameMouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
		{
			if (e.Button == MouseButtons.Right)
			{
				this.contextMenuStrip.Show(slotName.PointToScreen(e.Location));
			}
			else if (e.Button == MouseButtons.Left)
			{
				DoDragDrop(this, DragDropEffects.All);
			}
		}
		
		public void HideSlot()
		{
			Hide();
			((NodePanel)Parent).Reorganize();
		}
		
		public void ShowSlot()
		{
			Show();
			((NodePanel)Parent).Reorganize();
		}
		
		public void Attach()
		{
			if (Slot.Active && ProjectManager.Instance.UI.ShowUpdate && input != null)
			{
				input.Slot.ValueChanged += new ValueChangedEventHandler(ValueChanged);
			}
		}
		
		public void Detach()
		{
			if (input != null)
			{
				input.Slot.ValueChanged -= new ValueChangedEventHandler(ValueChanged);
			}
		}
		
		public bool Active
		{
			set 
			{
				if (input != null)
				{
					if (Slot.Active && value == false)
					{
						Detach();
					}
					else if (!Slot.Active && value == true)
					{
						Attach();
					}
				}
				
				Slot.Active = value;
				activeEventHandling.CheckState = value ? CheckState.Checked : CheckState.Unchecked;
			}
			get { return Slot.Active; }
		}
		
		void ActiveEventHandlingClick(object sender, System.Windows.Forms.MouseEventArgs e)
		{
			Active = !Active;
		}
		
		void InputSlotPanelDragEnter(object sender, System.Windows.Forms.DragEventArgs e)
		{
			IDataObject o = e.Data;
			if (o.GetDataPresent(typeof(OutputSlotPanel)))
			{
				OutputSlotPanel p = (OutputSlotPanel) o.GetData(typeof(OutputSlotPanel));
				//if (p.Slot.Value.GetType() == this.Slot.DefaultValue.GetType())
				if (Slot.Allowed(p.Slot.Value))
				{
					e.Effect = DragDropEffects.Move;
				}
				return;
			}
			
			e.Effect = DragDropEffects.None;
			
		}
		
		void InputSlotPanelDragDrop(object sender, System.Windows.Forms.DragEventArgs e)
		{
			IDataObject o = e.Data;
			if (o.GetDataPresent(typeof(OutputSlotPanel)))
			{
				OutputSlotPanel p = (OutputSlotPanel) o.GetData(typeof(OutputSlotPanel));
				UnConnect();
				Connect(p);
				Parent.Parent.Invalidate();

			}
		}
		
		void SlotValueKeyUp(object sender, System.Windows.Forms.KeyEventArgs e)
		{
			try
			{
				InputSlot s = (InputSlot)Tag;
				s.Parse(slotValue.Text);
				s.Owner.Update(sender);
			}
			catch {}
		}
		
		void MenuItemHideClick(object sender, System.EventArgs e)
		{
			HideSlot();
		}
		
		void InputSlotPanelMouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
		{
			if (e.Button == MouseButtons.Right)
			{
				this.contextMenuStrip.Show(slotName.PointToScreen(e.Location));
			}
			else if (e.Button == MouseButtons.Left)
			{
				DoDragDrop(this, DragDropEffects.All);
			}
		}
		

	}
}
